import Path from "path";

// rollup-plugin-delete 删除指定目录
import del from "rollup-plugin-delete";
import alias from "@rollup/plugin-alias";
import vuePlugin from "rollup-plugin-vue";
import globalStyles from "rollup-plugin-vue-global-styles";
import eslint from "@rollup/plugin-eslint";

// rollup-plugin-babel 转换 ES6 / 7 代码
import { babel } from "@rollup/plugin-babel";

// rollup 打包 library 时，无法对 node_modules 的文件进行打包，所以需要引入 rollup-plugin-node-resolve 来使用第三方模块
// rollup 无法识别 node_modules 中的包，帮助 rollup 查找外部模块，然后导入
// rollup-plugin-node-resolve 插件告诉 Rollup 如何搜寻外部依赖。
import { nodeResolve } from "@rollup/plugin-node-resolve";

/**
 * rollup 编译源码中的模块引用默认只支持 ES6+ 的模块方式 import/export
 * 而第三方模块大部分都是 commonjs 格式的，要在 rollup 中使用必须先转为 ES6 语法，所以需要引入 rollup-plugin-commonjs 插件
 */
//  将 CommonJS 模块转换为 ES6 供 rollup 处理
import commonjs from "@rollup/plugin-commonjs";

import json from "@rollup/plugin-json";

// @rollup/plugin-replace 替换待打包文件里的一些变量，如 process 在浏览器端是不存在的，需要被替换
import replace from "@rollup/plugin-replace";
import postcss from "rollup-plugin-postcss";

// @rollup/plugin-image 处理 img 元素引入的图片资源
import image from "@rollup/plugin-image";

// 按需打包字体图标
import font from "rollup-plugin-font";

// 多入口
import multi from "@rollup/plugin-multi-entry";

import html from "@rollup/plugin-html";

/**
 * 开发模式。主要有以下几点要素：
 * 1. 本地开发的 HTTP 服务
 * 2. 生成开发调试的 sourceMap 文件
 * 3. 不能混淆，保证编译后代码的可读性
 */
import serve from "rollup-plugin-serve";
import livereload from "rollup-plugin-livereload";

/**
 * 前端代码生产模式主要有以下几点要素：
 * 1. 保证代码混淆，编译结果不可读
 * 2. 体积压缩
 * 3. 信息脱敏
 */
// rollup-plugin-uglify 只能压缩和转换 es5 语法，如果是 es6+ 请使用 rollup-plugin-uglify-es
// rollup-plugin-terser 用于压缩 ES6 代码，功能和 uglify-js 相同，但 uglify-js 不支持 ES6 所以有了这个插件。
// import { uglify } from "rollup-plugin-uglify";
import { terser } from "rollup-plugin-terser";
import dotenv from "dotenv";
import { version } from "./package.json";

const { entry } = require("./entry.config.js");
const isDev = process.env.NODE_ENV === "development";
let patterns = [];
if (isDev) {
  patterns = patterns.concat([Path.resolve(__dirname, "styles/var.development.scss")]);
  dotenv.config({
    path: Path.resolve(process.cwd(), ".env.development"),
  });
} else {
  patterns = patterns.concat([Path.resolve(__dirname, "styles/var.scss")]);
  dotenv.config();
}

const config = {
  // 入口
  input: Path.resolve(__dirname, "vue-views", entry, "index"),

  output: {
    // 输出文件
    file: Path.resolve(__dirname, "dist", `${entry}.js`),

    /**
     * 输出格式：amd、esm、iife、umd、cjs（CommonJS）
     * 注意：如果是 umd 格式，必须指定模块的名称，通过 name 属性来实现
     */
    format: "umd",

    // 将作为全局变量挂在 window(浏览器环境) 下：window.A=...
    // //当format为iife和umd时必须提供，将作为全局变量挂在window下
    name: "A",
    // sourcemap: true,

    /**
     * globals 值是一个对象，key 表示使用的模块名称（npm模块名），value 表示在打包文件中引用的全局变量名
     * 跟 external 配套使用的
     */
    globals: {
      vue: "Vue",
      BMap: "BMap",
    },
  },

  /**
   * external 可跟 globals 配套使用
   * external 属性忽略打包的模块，使其作为单独的模块（或文件）来使用，方便浏览器进行缓存
   * 其值可以是一个字符串数组或一个方法
   */
  external: ["vue", "BMap"],

  // 插件的添加顺序决定了它们在打包过程中的使用顺序
  plugins: [
    // multi(),
    alias({
      entries: {
        "@components": Path.resolve(__dirname, ""),
      },
      customResolver: nodeResolve({
        extensions: ['.mjs', '.js', '.jsx', '.json', '.sass', '.scss']
      })
    }),
    json(),
    image(),
    // font({
    //   include: [
    //     "assets/font" // 这里根据自己使用的库修改
    //   ],
    //   // svg: "./node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.svg",
    //   outDir: "dist/fonts"
    // }),

    // 使用 JSON.stringify() 确保值被双引号包裹
    replace({
      preventAssignment: true,
      exclude: "node_modules/**",
      "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
    }),
    globalStyles({
      patterns,
      debug: true
    }),
    vuePlugin({
      // 把单文件组件中的样式，插入到 html 中的 style 标签
      css: false,
      // 把组件转换成 render 函数
      // compileTemplate: true
    }),
    del({
      targets: "dist/*",
    }),
    nodeResolve({
      jsnext: true, // jsnext 属性是为了帮助 Node 模块迁移到 ES2015 的一部分

      // main 和 browser 属性帮助插件决定哪个文件应该被 bundle 文件使用。
      main: true,
      browser: true,
      // module: false, // <-- this library is not an ES6 module
      // browser: true, // <-- suppress node-specific features
      // module: true, // ES6 模块尽可能使用 module 字段
      // preferBuiltins: false,
      extensions: [".vue"]
    }),
    commonjs({
      // include: [],
      // exclude: [],
      // namedExports: {}
    }),

    postcss({
      extract: true, // 是否使用 CSS 分离插件 ExtractTextPlugin，采用独立样式文件载入，不采用 <style>
      // extract: Path.resolve(__dirname, "dist/filename.css"),
      // plugins: [],
    }),
    // eslint(),
    babel({
      exclude: "node_modules/**",
      // babelHelpers: 'bundled',
      // / 当启用沙箱 polyfill 时，需要设定为 runtime
      babelHelpers: "runtime",
      // plugins: [
      //   "external-helpers"
      // ],
      // externalHelpers: true,
    }),
    html({
      attributes: {
        html: {
          lang: "en"
        },
        link: [
          "./dist/index.css"
        ],
        script: [
          "./dist/index.js",
          "./dist/index.js"
        ]
      },
      fileName: "home.html", // default index.html
    })
  ],
};

if (isDev) {
  // 开启 sourcemaps
  config.output.sourcemap = true;
  config.plugins.push(
    serve({
      port: "8089",
      host: "0.0.0.0",
      // open: true, // 是否打开浏览器
      contentBase: [Path.resolve(__dirname), Path.resolve(__dirname, "dist")], // 入口html的文件位置
      // historyApiFallback: true,
    }),
    livereload()
  );
} else {
  // 设置头部注释信息
  config.output.banner = `
    /**
     * @Author lei
     * @Date ${new Date().getFullYear()}
     * @${version}
     */`;

  // 设置尾部注释信息
  config.output.footer = `/** ${new Date()} **/`;
  config.output.sourcemap = false;
  config.plugins.push(
    terser({
      compress: {
        drop_console: true,
      },
    }),
    // 或
    // uglify({
    //   compress: {
    //     pure_getters: true,
    //     unsafe: true,
    //     unsafe_comps: true,
    //   },
    //   warnings: false,
    // })
  );
}

export default config;

// const configList = entry.map(_ => {
//   console.log(_, '_');
//   return {
//   input: "vue-views/index/index.js",

//   output: {
//     dir: "dist",
//     format: "umd", // 通用模块定义
//   },}
// });

// 通过配置 target 属性来输出多个打包文件：
// export default {
//   entry: "index.js",
//   targets: [
//     {
//       dest: "dist/bundle.cjs.js",
//       format: "cjs",
//     },
//     {
//       dest: "dist/bundle.umd.js",
//       moudleName: "res",
//       format: "umd",
//     },
//     {
//       dest: "dist/bundle.es.js",
//       format: "es",
//     },
//   ]
// }

// export default configList;
